﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BizAppFactory.Domain;
using Microsoft.VisualStudio.Modeling;

namespace BizAppFactory.Domain
{
    public partial class BizAppDomainModel
    {
        public List<Association> ManyToManyAssociations
        {
            get 
            {
                List<Association> manyToManyAssociations = new List<Association>();
                foreach(DomainClass domainClass in this.DomainClasses)
                {
                    foreach (Association assoc in Association.GetLinksToSourceClasses(domainClass))
                    {
                        if (
                                (assoc.SourceMultiplicity == AssociationMultiplicityEnum.ZeroOrMany ||
                                assoc.SourceMultiplicity == AssociationMultiplicityEnum.OneOrMany)
                                &&
                                (assoc.TargetMultiplicity == AssociationMultiplicityEnum.ZeroOrMany ||
                                assoc.TargetMultiplicity == AssociationMultiplicityEnum.OneOrMany)
                            )
                        {
                            manyToManyAssociations.Add(assoc);
                        }
                    }
                }

                return manyToManyAssociations;
            }
        }

        public List<DomainClass> DomainClasses
        {
            get
            {
                List<DomainClass> domainClasses = new List<DomainClass>();
                AddFromDomainElementList(this.DomainElements, domainClasses);
                RecurseModules(this.Modules, domainClasses);

                return domainClasses;
            }
        }

        void RecurseModules(LinkedElementCollection<Module> moduleList, List<DomainClass> domainClasses)
        {
            foreach (Module module in moduleList)
            {
                AddFromDomainElementList(module.DomainElements, domainClasses);
                AddFromAggreagateList(module.Aggregates, domainClasses);
                AddFromCRUDList(module.CRUDApplicationServices, domainClasses);

                if (module.ChildModules.Count > 0)
                {
                    RecurseModules(module.ChildModules, domainClasses);               
                }
            }
        
        }

        void AddFromCRUDList(LinkedElementCollection<CRUDApplicationService> crudServices, List<DomainClass> domainClasses)
        {
            foreach (CRUDApplicationService crudService in crudServices)
            {
                foreach (DomainClass domainClass in crudService.DomainClasses)
                {
                    domainClasses.Add(domainClass);
                }

                foreach (Aggregate aggreagte in crudService.Aggregates)
                {
                    AddFromAggreagateList(crudService.Aggregates, domainClasses);
                }
            }
        }

        void AddFromAggreagateList(LinkedElementCollection<Aggregate> aggregates, List<DomainClass> domainClasses)
        {
            foreach (Aggregate aggregate in aggregates)
            {
                foreach (DomainClass domainClass in aggregate.DomainClasses)
                {
                    domainClasses.Add(domainClass);
                }
            }
        }
        void AddFromDomainElementList(LinkedElementCollection<DomainElements> domainElements, List<DomainClass> domainClasses)
        { 
                foreach (DomainElements domainElement in domainElements)
                {
                    if (domainElement is DomainClass)
                    {
                        domainClasses.Add((DomainClass)domainElement);
                    }                         
                }
        }



    }
}
